package com.njcc.control;

import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.njcc.po.FileInfo;
import com.njcc.service.impl.PrintInfoServiceImpl;
import com.njcc.util.DBCon;
import com.njcc.util.JsonConfigUtil;
import com.njcc.util.OKHttpUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * 确认客户端的支付信息，成功则进行打印操作，同时记录文件信息
 */
@WebServlet("/ConfirmPayServlet")
public class ConfirmPayToPrintServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    private static final Logger logger = LogManager.getLogger(ConfirmPayToPrintServlet.class);
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ConfirmPayToPrintServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        PrintWriter out=response.getWriter();
		/*
		  通过流获取客户端发送的支付信息
		 */
		InputStream inputStream = request.getInputStream();
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] b = new byte[1024];
		int len = 0;
		while((len = inputStream.read(b)) != -1){
			baos.write(b, 0 , len);
		}
		String money = URLDecoder.decode(baos.toString(), "UTF-8");//将获得的流数据解码得到支付的钱数
        
        /*
         拿到存在application中的打印文件的信息fileInfo
         */
		FileInfo fileInfo = (FileInfo)getServletContext().getAttribute("fileInfo");
		double cost =fileInfo.getCost();//得到服务器中存储的消费金额信息
		
		/*
		 * 当支付的价钱与服务器中的价钱信息相等时，才会执行打印
		 */
		if(cost == Double.parseDouble(money)){
            //发送支付是否成功信息
			out.write("ok");
            logger.info("返回支付成功结果给客户端");
            //向数据库中记录打印文件的信息
			new PrintInfoServiceImpl().insertPrint(fileInfo);
            HashMap<String, String> map = new HashMap<>();
            map.put("fileName", fileInfo.getName());
			//开启子线程向专门负责打印的servlet发起打印请求
            new Thread(new Runnable() {
                @Override
                public void run() {
                    OKHttpUtil.httpJsonPost(JsonConfigUtil.getJsonConfigValue("printer-server-host")+"/printServlet",new Gson().toJson(map));
                }
            }).start();
            //toPrint(fileInfo.getName());
            
			getServletContext().removeAttribute("fileInfo");//销毁fileInfo信息
		}
		
		/*
		 * 关闭流
		 */
		baos.close();
		inputStream.close();
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
	
	/**
	 * 连接打印机，并且打印文件
	 * @param name 文件名
	 */
	private void toPrint(String name){
		
		String path= DBCon.file_Path+name;	//获得文件的存储位置
        logger.info("开始打印");
        logger.info("文件路径"+path);
        logger.info("打印机的名字:"+JsonConfigUtil.getJsonConfigValue("printer-name"));
        try {
            ComThread.InitSTA();
            logger.info("InitSTA success");
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(e);
        }
        ActiveXComponent word=new ActiveXComponent("Word.Application");
        logger.info("ActiveXComponent--word:"+word);
        //指定打印机的名字
        word.setProperty("ActivePrinter", new Variant(JsonConfigUtil.getJsonConfigValue("printer-name")));
        //设置后台静默处理
		Dispatch.put(word, "Visible", new Variant(false));
		Dispatch docs=word.getProperty("Documents").toDispatch();
        logger.info("docs:"+docs);
        Dispatch doc=Dispatch.call(docs, "Open", path).toDispatch();
        logger.info("doc:"+doc);
		try {
			Dispatch.call(doc, "PrintOut");//执行打印
            logger.info("打印成功");
		} catch (Exception e) {
			e.printStackTrace();
            logger.info("打印失败");
            logger.info(e.toString());
		}finally{
			try {
				if(doc!=null){
					Dispatch.call(doc, "Close",new Variant(0));
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			//释放资源
			ComThread.Release();
		}
	}

}
